package com.jd.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.jd.client.JwtToken;
import com.jd.client.OAuth2FeignClient;
import com.jd.entity.Menu;
import com.jd.model.LoginResult;
import com.jd.service.LoginService;
import com.jd.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import static org.springframework.http.HttpStatus.*;

/**
 * @author wangshuping
 * @version 1.0
 * @date 2021/11/21 14:45
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    public static String LOGIN_TYPE = "admin_type";
    public static String GRANT_TYPE = "password";

    @Value("${basic.token:Basic amQtYXBpOmpkLXNlY3JldA==}")
    private String basicToken;

    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    @Autowired
    private MenuService menuService;


    @Override
    public LoginResult login(String username, String password) {
        //调用授权服务获取token
        log.info("用户{}开始登录", username);
        ResponseEntity<JwtToken> responseEntity = null;
        try {
            responseEntity = oAuth2FeignClient.authToken(username, password, LOGIN_TYPE, GRANT_TYPE, basicToken);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (responseEntity != null && OK != responseEntity.getStatusCode()) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = responseEntity.getBody();
        log.info("远程调用授权服务器成功,获取的token为{}", JSON.toJSONString(jwtToken, true));
        String token = jwtToken.getAccessToken();

        //解析jwt
        Jwt jwt = JwtHelper.decode(token);
        JSONObject jwtJson = JSON.parseObject(jwt.getClaims());
        Long userId = jwtJson.getLong("user_name");

        //查询菜单数据
        List<Menu> menuList = menuService.getMenuListByUserId(userId);

        //查询权限数据(从token中解析)
        JSONArray jsonArray = jwtJson.getJSONArray("authorities");
        List<SimpleGrantedAuthority> authorities = jsonArray.stream()
                .map(json -> new SimpleGrantedAuthority(json.toString()))
                .collect(Collectors.toList());


        return new LoginResult(jwtToken.getTokenType() + " " + token, userId, menuList, authorities);
    }

}
